# 工资个税计算工具 v0.1 20210925
'''
20211011 增加导出模块代码，框架基本完成
20211013 完善逻辑
20211014 农行导出加表头，年金扣税比例判断（工资表实现吧），身份证字段类型，数值型四舍五入
20211015 统一文件路径参数
20211016 待完成 合并数据的数据类型统一，零工资或新增人员的规范处理，数据填充；工资表的数据回写；身份证格式；两位小数
20211019 完成xlwt应用，实现excel读写，实现四舍五入，shutil实现数据复制
'''
import pandas as pd
import h5py
import sys, time, os, shutil
import re
import xlrd, xlwt
from xlutils.copy import copy
# import xlutils
from decimal import Decimal,ROUND_HALF_UP
import warnings

# 忽略不支持xlwt警告
warnings.filterwarnings("ignore")

# pandas设置
pd.set_option('display.max_rows', 200)
pd.set_option ('display.max_colwidth',100)
pd.get_option('display.max_columns',100)
pd.set_option( 'display.precision',2)

# 全局变量

# 版本号
ver_num = 0.1

# 原始工资表应缴个税 实发工资所在列编号
tax_col = 57
salary_col = 59

# 系统导出工资表应缴个税、实发工资所在列编号
tax_col_sys = 46
salary_col_sys = 48
# 累计数据表从税务局导出表的截取字段
l_name_list0 = ['工号', '姓名', '证件类型', '证件号码', '税款所属期起', '税款所属期止', '累计收入额', '累计免税收入', '累计减除费用',
          '累计专项扣除', '累计子女教育支出扣除', '累计继续教育支出扣除', '累计住房贷款利息支出扣除', '累计住房租金支出扣除',
          '累计赡养老人支出扣除', '累计其他扣除', '累计准予扣除的捐赠', '累计应纳税所得额', '累计应纳税额',
          '累计减免税额', '累计应扣缴税额', '累计已预缴税额','累计应补(退)税额']

# 工资表主要字段
y_name_list = ['工号', '姓名', '证照类型', '证照号码','银行卡号', '基本工资', '岗位工资', '十三薪', '加班费', '绩效奖金', '其他收入1', '其他收入2',
         '差旅补贴', '交通补贴', '物业补贴', '伙食补贴', '儿童节补贴', '防暑降温费', '取暖费', '劳动保护费', '补充医疗', '其他福利1',
         '其他福利2', '事假扣发', '其他扣发1', '其他扣发2', '本期收入','其中免税收入','医保个人部分','养老个人部分','失业个人部分','社保公司小计', '社保个人小计', '公积金公司部分',
         '公积金个人部分', '专项扣除合计', '年金公司缴纳', '年金个人缴纳', '税优健康险','税延养老险','其他扣除（其他）','其他扣除合计', '免除费用', '专项附加扣除小计',
        '允许扣除捐赠','减免税额','应缴个税','代扣工会经费', '实发工资']

# 建行工资代发表字段
d_list_ccb = ['序号（必填）', '账号（必填）', '户名（必填）', '金额（必填）', '跨行标识（选填 建行填0 他行填1）',
              '行名（跨行业务与联行行号不能同时为空）', '联行行号（跨行业务与行名不能同时为空）', '摘要（选填 显示在收款账户流水明细中）',
              '备注（选填）']

# 农行工资代发表字段
d_list_abc = ['编号','收款方账号','收款方户名','金额','备注（附言）']

# 文件存放路径参数
in_path = 'file_in'
data_path = 'data_h5'
gzb_path = 'file_out_gzb'
sbb_path = 'file_out_sbb'
dfb_path = 'file_out_dfb'
ljb_path = 'file_out_ljb'


# 启动界面函数
def start():
    print('*' * 80)
    print('欢迎使用工资个税计算小工具')
    print('当前版本号', ver_num, '作者：lcx')
    print('系统功能介绍：')
    print('【数据初始化】第一次使用本系统，请先进行数据初始化，具体操作方法见使用说明。')
    print('【个税计算】系统自动计算当月应缴个税，使用前须将的原始工资表放到file_in目录。')
    print('【报表导出】导出各月度的工资表、个税申报表、银行工资代发表及累计数据汇总表。')
    print('【使用说明】工资个税计算小工具的使用说明。')
    print('*' * 80)


# 进度条函数
def progress():
    for i in range(100):
        k = i + 1
        str1 = '>' * (i // 2) + ' ' * ((100 - k) // 2)
        sys.stdout.write('\r' + str1 + '[%s%%]' % (i + 1))
        sys.stdout.flush()
        time.sleep(0.001)
    print('\n')

# 初始化函数
def csh():
    print('>>>>>>>>请将初始化文件放入file_in文件夹，文件名为：初始化数据表.xls ')
    print('>>>>>>>>请将初始化文件放好后请按回车键继续')
    input()
    try:
        l_data = pd.read_excel(in_path + r'/初始化数据表.xls',dtype={'证件号码':'str','税款所属期起':'str', '税款所属期止':'str'},header=[0])
    except:
        print('未找到初始化文件或文件不合规范')
    else:
        print('初始化文件读取成功，按回车键继续')
        input()
    print('>>>>>>>>>>>>>>>>>>>>开始处理初始化数据<<<<<<<<<<<<<<<<<<<')
    # 截取与累计数据相关的字段
    l_data = l_data[l_name_list0]
    # print(l_data)
    # 去掉空行
    #l_data = l_data.dropna(how='all',inplace=True)
    # print(l_data)
    l_data= l_data.astype({'工号':'int64','累计收入额': 'float64', '累计免税收入': 'float64', '累计减除费用': 'float64', '累计专项扣除': 'float64',
                      '累计子女教育支出扣除': 'float64', '累计继续教育支出扣除': 'float64', '累计住房贷款利息支出扣除': 'float64',
                      '累计住房租金支出扣除': 'float64', '累计赡养老人支出扣除': 'float64', '累计其他扣除': 'float64', '累计准予扣除的捐赠': 'float64',
                      '累计应纳税所得额': 'float64', '累计应纳税额': 'float64', '累计减免税额': 'float64',
                      '累计应扣缴税额': 'float64', '累计已预缴税额': 'float64', '累计应补(退)税额': 'float64'})
    # 截取月度信息、员工数信息
    l_mon = l_data.iat[0, 5][0:7]
    l_num = l_data.shape[0]
    progress()
    print('>>>>>>>>数据初始化完成,共导入截至 %s 月 %s 名员工数据<<<<<<<<' % (l_mon, l_num))
    print(l_data)

    print('>>>>>>>>>>>>>>>>>>>>开始将初始化数据存入数据库<<<<<<<<<<<<<<<<<<<')
    l_mon = 'L' + str(l_mon[0:4]) + str(l_mon[5:7]) + '01'
    store = pd.HDFStore(data_path + r'/%s.h5' % (str(l_mon[1:5])), mode='a')
    store.put(key=l_mon, value=l_data, format='table')
    store.close()
    progress()
    print('>>>>>>>>>>>>>>>>>>>>初始化数据已存入数据库<<<<<<<<<<<<<<<<<<<')
    print('按回车返回导航界面')
    input()
    navi()


# 税率函数
def sl(ynse):
    # 适用税率
    sysl = 0.00
    # 速算扣除数
    sskcs = 0.00
    if 0<=ynse <= 36000.00:
        sysl = 0.03
        sskcs = 0.00
    elif 36000.00 < ynse <= 144000.00:
        sysl = 0.10
        sskcs = 2520.00
    elif 144000.00 < ynse <= 300000.00:
        sysl = 0.20
        sskcs = 16920.00
    elif 300000.00 < ynse <= 420000.00:
        sysl = 0.25
        sskcs = 31920.00
    elif 420000.00 < ynse <= 660000.00:
        sysl = 0.30
        sskcs = 52920.00
    elif 660000.00 < ynse <= 960000.00:
        sysl = 0.35
        sskcs = 85920.00
    elif ynse > 960000.00:
        sysl = 0.45
        sskcs = 181920.00
    return [sysl, sskcs]


# 导入某文件夹下所有工资文件
def get_flist(path):
    f_list = []
    # 系统自带函数os.walk，用于遍历文件夹中的所有文件
    for root, dirs, files in os.walk(path):
        if files:  # 当files不为空的时候
            for f in files:
                if f.endswith('.xls') and f.startswith('Y'):
                    f_list.append(f[:9])
    return sorted(f_list)


# 计算个数函数
def jsgs():
    print('>>>>>>>>请将原始工资表放入file_in文件夹，文件名形如：Y20210601.xls')
    print('>>>>>>>>请将原始工资表文件放好后请按回车键继续')
    input()
    print('检测到file_in目录存在以下月度工资表文件')
    f_dir = os.path.dirname(os.path.abspath(__file__))
    f_list = get_flist(f_dir +'/'+ in_path)
    print(f_list)
    print('请输入导入的文件名称，不含文件类型后缀，如Y20210601')
    while True:
        y_name = input()
        if y_name in f_list:
            break
        else:
            print('输入错误，请重新输入')

    print('>>>>>>>>>>>>>>>>>>>>>开始导入月度工资表数据<<<<<<<<<<<<<<<<<<<<<')
    m_data = pd.read_excel(in_path+'/'+'%s.xls' % y_name, dtype={'证照号码':'str','银行卡号':'str'},header=[1])
    m_data = m_data.astype(
        {'工号':'int64','本期收入': 'float64', '其中免税收入': 'float64', '医保个人部分': 'float64', '养老个人部分': 'float64', '失业个人部分': 'float64',
         '社保个人小计': 'float64', '公积金个人部分': 'float64', '专项扣除合计': 'float64', '年金个人缴纳': 'float64',
         '税优健康险': 'float64', '税延养老险': 'float64', '其他扣除（其他）': 'float64', '其他扣除合计': 'float64', '免除费用': 'float64',
         '子女教育扣除': 'float64', '继续教育扣除': 'float64', '贷款利息扣除': 'float64', '房租扣除': 'float64', '赡养老人扣除': 'float64',
         '专项附加扣除小计': 'float64', '允许扣除捐赠': 'float64', '减免税额': 'float64', '应缴个税': 'float64', '代扣工会经费': 'float64',
         '实发工资': 'float64'})
    m_mon = y_name[5:7]
    m_year = y_name[1:5]
    m_num = y_name[7:]
    staff_num = m_data.shape[0]
   # m_data = m_data.dropna(axis=0,how='all',subset=['姓名','本期收入','实发工资'], inplace=True)
    progress()
    print('>>>>>>>>数据导入完成,本次为 %s 年第 %s 月第 %s 批次发放，共 %s 名员工数据<<<<<<<<' % (m_year,m_mon, m_num, staff_num))
    print(m_data)

    print('>>>>>>>>>>>>>>>>>>>>开始读取累计数据表明细<<<<<<<<<<<<<<<<<<<<<')
    progress()
    store = pd.HDFStore(data_path+r'/%s.h5' % m_year, mode='a')
    hlist = []
    for key in store.keys():
        key = key[-9:]
        hlist.append(key)
    print('数据库中存储的累计数据表明细如下：')
    for i in hlist:
        if i.startswith('L'):
            print(i)
    print('请输入要读取的累计数据表名称，如：L20210601。请确保是本次发薪最近一次的数据')
    while True:
        l_name = input()
        if l_name in hlist:
            break
        else:
            print('输入错误，请重新输入')
    l_data = store[l_name]

    print('>>>>>>>>>>>>>>>>>开始进行月度数据与累计数据合并计算<<<<<<<<<<<<<<<<<')
    hb = l_data.merge(m_data, how='outer', on='姓名')
    hb['证件类型'].fillna(hb['证照类型'], inplace=True)
    hb['证件号码'].fillna(hb['证照号码'], inplace=True)
    hb['证照类型'].fillna(hb['证件类型'], inplace=True)
    hb['证照号码'].fillna(hb['证件号码'], inplace=True)
    hb['税款所属期起'].fillna(method='ffill', inplace=True)
    hb['税款所属期止'].fillna(method='ffill', inplace=True)
    hb['工号_x'].fillna(method='ffill', inplace=True)
    hb['工号_y'].fillna(method='ffill', inplace=True)
    hb['部门'].fillna('未知', inplace=True)
    hb['职级'].fillna('未知', inplace=True)
    hb['银行卡号'].fillna(88888888, inplace=True)
    hb.fillna(0.00, inplace=True)
    hbx = hb.copy()
    hbx['累计收入额'] = hbx['累计收入额'] + hbx['本期收入']
    hbx['累计免税收入'] = hbx['累计免税收入'] + hbx['其中免税收入']
    hbx['累计减除费用'] = hbx['累计减除费用'] + hbx['免除费用']
    hbx['累计专项扣除'] = hbx['累计专项扣除'] + hbx['专项扣除合计']
    hbx['累计子女教育支出扣除'] = hbx['累计子女教育支出扣除'] + hbx['子女教育扣除']
    hbx['累计继续教育支出扣除'] = hbx['累计继续教育支出扣除'] + hbx['继续教育扣除']
    hbx['累计住房贷款利息支出扣除'] = hbx['累计住房贷款利息支出扣除'] + hbx['贷款利息扣除']
    hbx['累计住房租金支出扣除'] = hbx['累计住房租金支出扣除'] + hbx['房租扣除']
    hbx['累计赡养老人支出扣除'] = hbx['累计赡养老人支出扣除'] + hbx['赡养老人扣除']
    hbx['累计其他扣除'] = hbx['累计其他扣除'] + hbx['其他扣除合计']
    hbx['累计准予扣除的捐赠'] = hbx['累计准予扣除的捐赠'] + hbx['允许扣除捐赠']
    hbx['累计减免税额'] = hbx['累计减免税额'] + hbx['减免税额']
    hbx['累计应纳税所得额'] = hbx['累计收入额'] - hbx['累计免税收入'] - hbx['累计减除费用'] - hbx['累计专项扣除'] - hbx['累计子女教育支出扣除'] - hbx[
        '累计继续教育支出扣除'] - hbx['累计住房贷款利息支出扣除'] - hbx['累计住房租金支出扣除'] - hbx['累计赡养老人支出扣除'] - hbx['累计其他扣除'] - hbx['累计准予扣除的捐赠']
    hbx['foo'] = hbx['累计应纳税所得额'].apply(lambda x: sl(x))
    hbx['税率'] = [i[0] for i in hbx['foo']]
    hbx['速算扣除数'] = [i[1] for i in hbx['foo']]
    hbx['累计应纳税额'] = hbx['累计应纳税所得额'] * hbx['税率'] - hbx['速算扣除数']
    hbx['累计应扣缴税额'] = hbx['累计应纳税额'] - hbx['累计减免税额']
    hbx['累计应补(退)税额'] = hbx['累计应扣缴税额'] - hbx['累计已预缴税额']
    hbx['实发工资'] = hbx['本期收入'] - hbx['其中免税收入'] - hbx['专项扣除合计'] - hbx['其他扣除合计'] - hbx['免除费用'] \
                  - hbx['专项附加扣除小计'] - hbx['累计应补(退)税额'] - hbx['代扣工会经费']
    progress()

    # 筛选本月新增人员
    df_new = hbx[hbx['累计收入额'] == hbx['本期收入']]
    df_new = df_new[['工号_y', '姓名', '证照类型', '证照号码', '累计收入额', '本期收入']]
    print('【本次较上次发薪新增人员】:')
    if df_new.empty:
        print('本次较上月发薪无新增人员')
    else:
        print(df_new)

    # 筛选本月减少人员
    df_old = hb[(hb['累计收入额'] > 0.01) & (hb['本期收入'] <= 0.01)]
    df_old = df_old[['工号_x', '姓名', '证照类型', '证照号码', '累计收入额', '本期收入']]
    print('【本次较上次发薪减少人员】:')
    if df_old.empty:
        print('本次较上月发薪无减少人员')
    else:
        print(df_old)
    print('>>>>>>>>>>>>>>>>>已完成数据合并，请按回车键确认后继续')
    input()

    print('>>>>>>>>>>>>>>>>>开始生成本月完整工资表,并存入数据库<<<<<<<<<<<<<<<<<')
    gzb = hbx.copy()
    gzb.rename(columns={'工号_y':'工号'},inplace=True)
    gzb['应缴个税'] = gzb['累计应补(退)税额']
    gzb = gzb[y_name_list]
    gzb = gzb[(gzb['实发工资']>=0.01) & (gzb['本期收入']>=0.01)]
    gzb.reset_index(drop=True, inplace=True)
    gzb['应缴个税'] = gzb['应缴个税'].apply(lambda x: float(Decimal(x*100).quantize(Decimal('1'),rounding =ROUND_HALF_UP)/100))
    gzb['实发工资'] = gzb['实发工资'].apply(lambda x: float(Decimal(x * 100).quantize(Decimal('1'), rounding=ROUND_HALF_UP) / 100))
    store.put(key=y_name, value=gzb, format='table')
    progress()
    print('>>>>>>>>>>>>>>>>>已生成本月完整工资表,并存入数据库')
    print(gzb)
    print('\n')
    shutil.copy2(in_path+'/'+'%s.xls' % y_name, gzb_path + '/'+'%s_系统补全.xls' % y_name)
    file_name = gzb_path + '/'+'%s_系统补全.xls' % y_name
    rb = xlrd.open_workbook(file_name, formatting_info=True)
    wb = copy(rb)
    ws = wb.get_sheet(0)
    for i in range(2, gzb.shape[0] + 2):
            ws.write(i, tax_col, gzb.iloc[i - 2, tax_col_sys])
            ws.write(i, salary_col, gzb.iloc[i - 2, salary_col_sys])
    wb.save(file_name)
    print('>>>>>>>>>>>>>>>>>已将%s年 %s 月第 %s 批次完整工资表导出至file_out_gzb文件夹'% (m_year,m_mon, m_num))
    print('\n')
    print('>>>>>>>>>>>>>>>>>开始更新截至本次发薪的累计数据表，并存入数据库<<<<<<<<<<<<<<<<<')
    ljb = hbx.copy()
    # 过滤已离职人员
    ljb = ljb[(ljb['实发工资'] >= 0.01) & (ljb['本期收入'] >= 0.01)]
    # 更新本月个税
    ljb['累计已预缴税额'] = ljb['累计已预缴税额'] + ljb['累计应补(退)税额']
    ljb.rename(columns={'工号_y': '工号'}, inplace=True)
    ljb = ljb[l_name_list0]
    ljb['税款所属期起']= y_name[1:5]+'-'+y_name[5:7]+'-'+'01'
    ljb['税款所属期止'] = y_name[1:5] + '-' + y_name[5:7] + '-' + '30'
    # 初始化应退补税
    ljb['累计应补(退)税额'] = 0.00
    ljb.reset_index(drop=True, inplace=True)
    ljb['累计应纳税额'] = ljb['累计应纳税额'].apply(lambda x: float(Decimal(x*100).quantize(Decimal('1'),rounding =ROUND_HALF_UP)/100))
    ljb['累计应扣缴税额'] = ljb['累计应扣缴税额'].apply(lambda x: float(Decimal(x*100).quantize(Decimal('1'), rounding=ROUND_HALF_UP) / 100))
    ljb['累计已预缴税额'] = ljb['累计已预缴税额'].apply(lambda x: float(Decimal(x*100).quantize(Decimal('1'), rounding=ROUND_HALF_UP) / 100))
    store.put(key='L' + y_name[1:], value=ljb, format='table')
    progress()
    print(ljb)
    print('>>>>>>>>>>>>>>>>>已更新截至本次发薪的累计数据表,并存入数据库')
    # print('\n')
    # ljb.to_excel(ljb_path+r'/L%s_sys.xls' % y_name[1:],index=False)
    # print('>>>>>>>>>>>>>>>>>已将%s年 %s 月第 %s 批次发薪后累计数据表导出至file_out_ljb文件夹' % (m_year, m_mon, m_num))
    store.close()
    print('\n')
    print('>>>>>>>>>>>>>>>>>按回车键返回导航界面')
    input()
    navi()

# 使用说明函数
def sysm():
    print('''使用说明：
     1、本工具主要实现企业发放工资时，代扣员工个税的计算并导出完整的工资表、代发工资表、个税申报表等。
     2、系统运行环境：windows 10,其他系统未测试，主要通过python及pandas、xlrd及xlwt等库实现。
     3、主要实现思路：假设发薪月为Y月，先从税局系统导出截至Y-1月的员工累计收入、累计抵扣数据，及累计已缴个税数据(可使用税务局导出数据
     的前提条件是企业已完成Y-1月个税申报，重要！)，初始化数据表可从税务局以下路径导出：【待补充】。小工具将累计信息及本月原
     始工资表（需先由企业编制好，代扣个税及实发工资信息留空）进行合并后按照税法规定的计算规则计算出本月应扣缴个税金额，并生成完整的工资表，还
     可根据相关信息生成其他报表。对于每年的1月份，尚无累计数据，初始化数据表内涉及金额的字段可留空。
     4、原始月度工资表、初始化数据表必须严格按照file_in文件夹内的模板格式填列，不能随意增删字段，否则小工具可能无法正常运行。
     5、文件结构：tax.exe为主程序，file_in文件夹存放初始化文件及各月度原始工资表，file_out_gzb文件夹存放导出的完整工资表，
     file_out_sbb文件夹存放导出的个税申报表，file_out_dfb文件夹存放导出的银行网银的工资代发表（文件夹内的两个银行代发模板文件不可以删除及改动），
     file_out_ljb文件夹存放导出的累计数据表，data_h5文件夹存放数据库文件。
     6、导入excel文件必须是xls为后缀名的，若为xlsx后缀，必须另存为xls为后缀名才可导入，否则可能导致小工具无法正常运行。
     7、文件命名规则：原始工资表文件名为：Y+四位年份+两位月份+两位批次代码，如2021年2月份发放第二次工资（部分企业绩效可能和工资分开发放），放入
     file_in文件夹内的原始工资表文件名应为：Y20210202.xls；从税务局导出的初始化数据表，文件名应统一修改为：初始化数据表.xls；累计数据表文件
     以大写字母L开头，后面和工资表规则一只，如L20210202则表示截至2021年2月第2次工资发放后的累计数据。
     8、小工具可能存在系统缺陷，务必与人工计算结果校对后才可使用相关导出结果！！,对于计算错误作者不承担任何责任''')
    print('>>>>>>>>>>>>>>>>>按回车键返回导航界面')
    input()
    navi()


# 报表导出函数
def bbdc():
    while True:
        print('请输入导出批次，如：20210701 为基于2021年7月份第1次工资发放生成的报表')
        s_mon = input()
        pattern = re.compile(r'202[123456789][01][0123456789][01][0123456789]')
        rzt = re.search(pattern, s_mon)
        if rzt:
            break
        else:
            print('输入错误，请重新输入')
    try:
        store = pd.HDFStore(data_path+r'/%s.h5' % (s_mon[0:4]), mode='r')
    except:
        print('未找到数据文件，请确认数据是否存在,系统将自动退出')
        return

    hlist = []
    for key in store.keys():
        key = key[-9:]
        hlist.append(key)
    while True:
        if ('Y'+s_mon in hlist) and('L'+s_mon in hlist):
            break
        else:
            print('所选月份数据不存在，,系统将自动退出')
            return


    while True:
        bbcode = input('请输入功能代码：1 个税申报表；2 工资代发表；3 月度工资表；4 累计数据表；5 返回主菜单 \n')

        if bbcode == '1':
            # 输出个税申报表
            print('>>>>>>>>>>>>>>>>>>>开始进行个税申报表导出<<<<<<<<<<<<<<<<<<<<')
            y_data_bb = store['Y' + s_mon]
            l_data_bb = store['L' + s_mon]
            print(y_data_bb)
            print(l_data_bb)
            hb = l_data_bb.merge(y_data_bb, how='outer', on='姓名')

            # hb.to_excel(r'合并导出20210701.xls')
            sbb = hb.copy()
            sbb['备注'] = ""
            sbb.rename(columns={'工号_y': '工号', '证照类型': '*证照类型', '证照号码': '*证照号码', '本期收入': '*本期收入',
                                 '其中免税收入': '本期免税收入', '其他扣除（其他）': '其他', '允许扣除捐赠': '其他准予扣除的捐赠额',
                                 '养老个人部分': '基本养老保险费', '医保个人部分': '基本医疗保险费', '失业个人部分': '失业保险费',
                                 '公积金个人部分': '住房公积金', '累计子女教育支出扣除': '累计子女教育', '累计继续教育支出扣除': '累计继续教育',
                                 '累计住房贷款利息支出扣除': '累计住房贷款利息', '累计住房租金支出扣除': '累计住房租金',
                                 '累计赡养老人支出扣除': '累计赡养老人', '年金个人缴纳': '企业(职业)年金', '税优健康险': '商业健康保险',
                                 '税延养老险': '税延养老保险'}, inplace=True)

            sbb = sbb[['工号', '姓名','*证照类型', '*证照号码', '*本期收入', '本期免税收入', '基本养老保险费', '基本医疗保险费', '失业保险费', '住房公积金',
                        '累计子女教育', '累计继续教育', '累计住房贷款利息', '累计住房租金', '累计赡养老人', '企业(职业)年金', '商业健康保险',
                        '税延养老保险', '其他', '其他准予扣除的捐赠额', '减免税额', '备注']]
            sbb= sbb[(sbb['*本期收入'] >= 0.01)]
            sbb.to_excel(sbb_path+r'/%s个税申报表_系统导出.xls' % s_mon, index=False)
            progress()
            print('>>>>>>>>>>>>>>>>>>>个税申报表导出完毕，请在file_out_sbb目录中查看')
            break

        elif bbcode == '2':
            # 输出工资代发表
            print('>>>>>>>>>>>>>>>>>>>>开始进行工资代发表导出<<<<<<<<<<<<<<<<<<<<')
            y_data_bb = store['Y' + s_mon]
            dfb = y_data_bb[['工号', '银行卡号', '姓名', '实发工资']]
            dfb = dfb.astype({'工号': 'str', '银行卡号': 'str', '实发工资': 'float64'})
            while True:
                print('请选择代发银行代码：1 建设银行；2 农业银行')
                bank_code = input()
                if bank_code == '1':
                    ccb = pd.DataFrame(columns=d_list_ccb)
                    ccb['序号（必填）'] = dfb['工号']
                    ccb['账号（必填）'] = dfb['银行卡号']
                    ccb['户名（必填）'] = dfb['姓名']
                    ccb['金额（必填）'] = dfb['实发工资']
                    ccb['跨行标识（选填 建行填0 他行填1）'] =''
                    ccb['行名（跨行业务与联行行号不能同时为空）'] =''
                    ccb['联行行号（跨行业务与行名不能同时为空）'] =''
                    ccb['摘要（选填 显示在收款账户流水明细中）'] = s_mon + '工资'
                    ccb['备注（选填）'] =''
                    shutil.copy2(dfb_path + r'\建行模板.xls', dfb_path + r'\%s代发工资表_建行_系统导出.xls'%s_mon)
                    file_name = dfb_path + r'\%s代发工资表_建行_系统导出.xls'%s_mon
                    rb = xlrd.open_workbook(file_name, formatting_info=True)
                    wb = copy(rb)
                    print(ccb)
                    ws = wb.get_sheet(0)
                    for i in range(1, ccb.shape[0]+1):
                        for j in range(0, 9):
                            ws.write(i, j, ccb.iloc[i-1,j])
                    wb.save(file_name)
                    progress()
                    print('>>>>>>>>>>>>>>>>>>>工资代发表导出完毕，请在file_out_dfb目录中查看')
                    break

                elif bank_code == '2':
                    abc = pd.DataFrame(columns=d_list_abc)
                    abc['编号'] = dfb['工号']
                    abc['收款方账号'] = dfb['银行卡号']
                    abc['收款方户名'] = dfb['姓名']
                    abc['金额'] = dfb['实发工资']
                    abc['备注（附言）'] = s_mon + '工资'
                    # print(abc.dtypes)
                    shutil.copy2(dfb_path + r'\农行模板.xls', dfb_path + r'\%s代发工资表_农行_系统导出.xls' % s_mon)
                    file_name = dfb_path + r'\%s代发工资表_农行_系统导出.xls' % s_mon
                    rb = xlrd.open_workbook(file_name, formatting_info=True)
                    wb = copy(rb)
                    print(abc)
                    ws = wb.get_sheet(0)
                    for i in range(2, abc.shape[0] + 2):
                        for j in range(0, 5):
                            ws.write(i, j, abc.iloc[i - 2, j])
                    wb.save(file_name)
                    progress()
                    print('>>>>>>>>>>>>>>>>>>>工资代发表导出完毕，请在file_out_dfb目录中查看')
                    break
                else:
                    print('输入错误，请重新输入')

        elif bbcode == '3':
            # 输出月度工资表
            print('>>>>>>>>>>>>>>>>>>>>开始进行月度工资表导出<<<<<<<<<<<<<<<<<<<<')
            y_data_bb = store['Y' + s_mon]
            y_data_bb.to_excel(gzb_path+r'/Y%s工资表_系统导出.xls' % s_mon,index=False)
            progress()
            print('>>>>>>>>>>>>>>>>>>>月度工资表导出完毕，请在file_out_gzb目录中查看')
            break

        elif bbcode == '4':
            # 输出累计数据表
            print('>>>>>>>>>>>>>>>>>>>>开始进行累计数据表导出<<<<<<<<<<<<<<<<<<<<')
            l_data_bb = store['L' + s_mon]
            l_data_bb['累计应纳税额'] = l_data_bb['累计应纳税额'].apply(
                lambda x: float(Decimal(x * 100).quantize(Decimal('1'), rounding=ROUND_HALF_UP) / 100))
            l_data_bb['累计应扣缴税额'] = l_data_bb['累计应扣缴税额'].apply(
                lambda x: float(Decimal(x * 100).quantize(Decimal('1'), rounding=ROUND_HALF_UP) / 100))
            l_data_bb['累计已预缴税额'] = l_data_bb['累计已预缴税额'].apply(
                lambda x: float(Decimal(x * 100).quantize(Decimal('1'), rounding=ROUND_HALF_UP) / 100))
            l_data_bb.to_excel(ljb_path+r'/L%s累计数据表_系统导出.xls' % s_mon,index=False)
            progress()
            print('>>>>>>>>>>>>>>>>>>>累计数据表导出完毕，请在file_out_ljb目录中查看')
            break

        elif bbcode == '5':
            navi()
            break
        else:
            print('输入错误，请重新输入')
    store.close()
    print('>>>>>>>>>>>>>>>>>>>按回车键返回导航界面')
    input()
    navi()


# 菜单界面函数
def navi():
    while True:
        choice = input('请输入功能代码：1 数据初始化；2 个税计算；3 报表导出；4 使用说明；5 退出系统 \n')
        if choice == '1':
            csh()
            break
        elif choice == '2':
            jsgs()
            break
        elif choice == '3':
            bbdc()
            break
        elif choice == '4':
            sysm()
            break
        elif choice == '5':
            quit()
            break
        else:
            print('输入错误，请重新输入')
start()
navi()
